package com.ly.mp.busicen.rule.flow;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.ly.mp.busicen.rule.IRuleReload;
import com.ly.mp.busicen.rule.config.XruleConfig;
import com.ly.mp.busicen.rule.config.XruleExtendCfg;
import com.ly.mp.busicen.rule.flow.action.OperationType;

@Configuration
public class FlowActionLoader implements IRuleReload {
	
	private final Logger log = LoggerFactory.getLogger(FlowActionLoader.class);
	
	@Autowired
	ActionContainer actionContainer;
	
	@Autowired()
	NamedParameterJdbcTemplate jdbcTemplate;
	
	@Autowired
	XruleConfig xruleConfig;
	
	@PostConstruct
	public void load() {		
		xruleConfig.xruleDataLoadCfg().flowRuleLoading().loading(this,this::loadActions);		
	}
	
	public void loadActions() {
		actionContainer.setFragments(actionLoadInDb());
		if(xruleConfig.xruleExtendCfg().currentCustMode()) {
			actionContainer.setFragmentsCust(actionLoadInDbCust());
		}
		actionContainer.cleanCache();
	}
	
	/**
	 * 
	 * @Description: from t_prc_db_sence_datarule s right join t_prc_db_datarule r
	 */
	public List<Fragment>  actionLoadInDb() {
		List<Fragment> result=null;
		String SQL = "SELECT s.BUSINESSFLOW_SENCECODE,s.ACTION_CODE,s.ACTION_NAME,s.NEXT_ACTION_CODE,s.LOOP_ENABLE," + 
				" s.DATA_CODE,r.OPERATION_TYPE,s.MESSAGE_CODE,r.DATARULE_CHECK,s.CAR_BRAND_CODE,s.OEM_CODE," + 
				" s.ACTION_FILTER,r.DATARULE_CODE from "+xruleConfig.xruleDataCfg().flowRule()+" s right join "+xruleConfig.xruleDataCfg().dataRule()+" r " + 
				" on s.DATARULE_CODE = r.DATARULE_CODE and r.IS_ENABLE = '1' and s.IS_ENABLE = '1'";
		List<Map<String, Object>> results = jdbcTemplate.queryForList(SQL, new HashMap<String, Object>());
		result = results.stream().map(m->{
			null2Empty(m);
			Fragment fragment = new Fragment();
			fragment.setAction(m.get("ACTION_CODE").toString());
			fragment.setActionName(m.get("ACTION_NAME").toString());
			fragment.setBrand(m.get("CAR_BRAND_CODE").toString());
			fragment.setContent(m.get("DATARULE_CHECK").toString());
			fragment.setExtKey(m.get("DATA_CODE").toString());
			fragment.setFlow(m.get("BUSINESSFLOW_SENCECODE").toString());
			fragment.setMsg(m.get("MESSAGE_CODE").toString());
			fragment.setNextAction(m.get("NEXT_ACTION_CODE").toString());
			fragment.setOem(m.get("OEM_CODE").toString());
			fragment.setOperation(db2op(m));
			fragment.setLoopEnable(m.get("LOOP_ENABLE").toString());
			fragment.setFilter(m.get("ACTION_FILTER").toString());
			fragment.setRuleCode(m.get("DATARULE_CODE").toString());
			return fragment;
		}).collect(Collectors.toList());
		return result;		
	}
	
	public List<Fragment>  actionLoadInDbCust() {
		List<Fragment> result=null;
		String SQL = "SELECT s.BUSINESSFLOW_SENCECODE,s.ACTION_CODE,s.ACTION_NAME,s.NEXT_ACTION_CODE,s.LOOP_ENABLE," + 
				" s.DATA_CODE,r.OPERATION_TYPE,s.MESSAGE_CODE,r.DATARULE_CHECK,s.CAR_BRAND_CODE,s.OEM_CODE," + 
				" s.ACTION_FILTER,r.DATARULE_CODE from "+xruleConfig.xruleDataCfg().flowRule()+XruleExtendCfg.CUST_EXT+" s right join "
				+xruleConfig.xruleDataCfg().dataRule()+XruleExtendCfg.CUST_EXT+" r " + 
				" on s.DATARULE_CODE = r.DATARULE_CODE and r.IS_ENABLE = '1' and s.IS_ENABLE = '1'";
		List<Map<String, Object>> results = jdbcTemplate.queryForList(SQL, new HashMap<String, Object>());
		result = results.stream().map(m->{
			null2Empty(m);
			Fragment fragment = new Fragment();
			fragment.setAction(m.get("ACTION_CODE").toString());
			fragment.setActionName(m.get("ACTION_NAME").toString());
			fragment.setBrand(m.get("CAR_BRAND_CODE").toString());
			fragment.setContent(m.get("DATARULE_CHECK").toString());
			fragment.setExtKey(m.get("DATA_CODE").toString());
			fragment.setFlow(m.get("BUSINESSFLOW_SENCECODE").toString());
			fragment.setMsg(m.get("MESSAGE_CODE").toString());
			fragment.setNextAction(m.get("NEXT_ACTION_CODE").toString());
			fragment.setOem(m.get("OEM_CODE").toString());
			fragment.setOperation(db2op(m));
			fragment.setLoopEnable(m.get("LOOP_ENABLE").toString());
			fragment.setFilter(m.get("ACTION_FILTER").toString());
			fragment.setRuleCode(m.get("DATARULE_CODE").toString());
			return fragment;
		}).collect(Collectors.toList());
		return result;		
	}
	
	Map<String, Object> null2Empty(Map<String, Object> map){
		map.forEach((k,v)->{
			if (v==null) {
				map.put(k, "");
			}
		});
		return map;
	}
	
	private OperationType db2op(Map<String,Object> m) {
		try {
			return OperationType.valueOf(m.get("OPERATION_TYPE").toString());
		}catch(Exception e) {
			log.error("规则引擎配置加载失败:DATARULECODE[{}],OPERATIONTPYE[{}]",m.get("DATARULE_CODE"),m.get("OPERATION_TYPE"),e);
			throw e;
		}
	}
	
	@Override
	public boolean reload() {
		load();
		return true;
	}

}
